﻿#region << 文 件 说 明 >>

/*----------------------------------------------------------------
// 文件名称：DynamicData
// 创 建 者：杨程
// 创建时间：2021/9/15 14:09:59
// 文件版本：V1.0.0
// ===============================================================
// 功能描述：
//
//
//----------------------------------------------------------------*/

#endregion

namespace Vampirewal.Core;

/// <summary>
/// 自定义实现动态类
/// </summary>
public class DynamicData : DynamicObject
{
    internal Dictionary<string, object> Fields = new Dictionary<string, object>();

    /// <summary>
    /// 这个动态类中有多少个字段属性
    /// </summary>
    public int Count
    { 
        get
        {
            return Fields.Keys.Count; 
        } 
    }

    /// <summary>
    /// 添加字段
    /// </summary>
    /// <param name="name"></param>
    /// <param name="val"></param>
    public void Add(string name, object val = null)
    {
        if (!Fields.ContainsKey(name))
        {
            Fields.Add(name, val);
        }
        else
        {
            Fields[name] = val;
        }
    }

    /// <summary>
    /// 获取方法
    /// </summary>
    /// <param name="binder"></param>
    /// <param name="result"></param>
    /// <returns></returns>
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        if (Fields.ContainsKey(binder.Name))
        {
            result = Fields[binder.Name];
            return true;
        }
        return base.TryGetMember(binder, out result);
    }

    /// <summary>
    /// 设置
    /// </summary>
    /// <param name="binder"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        if (!Fields.ContainsKey(binder.Name))
        {
            Fields.Add(binder.Name, value);
        }
        else
        {
            Fields[binder.Name] = value;
        }
        return true;
    }

    /// <summary>
    /// 尝试执行
    /// </summary>
    /// <param name="binder"></param>
    /// <param name="args"></param>
    /// <param name="result"></param>
    /// <returns></returns>
    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        if (Fields.ContainsKey(binder.Name) &&
            Fields[binder.Name] is Delegate)
        {
            Delegate del = Fields[binder.Name] as Delegate;
            result = del.DynamicInvoke(args);
            return true;
        }
        return base.TryInvokeMember(binder, args, out result);
    }
}